package edu.hawaii.duedates;

import java.io.Serializable;
import java.util.Comparator;

/**
 * An object to hold the specifics on each borrowed item with a
 * respective due date. Can be used with any LibraryVault system.
 * 
 * @author Tyler Wolff and Scheller Sanchez
 */

public class ItemDue implements Serializable {
  
  private static final long serialVersionUID = 1L;
  
  private String itemLib;
  private String itemName;
  private String itemType;
  private String itemDueDate;
  
  /**
   * Constructs the basic ItemDue object.
   * 
   * @param itemLib The Name of the Library.
   * @param itemName The Name of the borrowed item.
   * @param itemType The type of item (ie: book, video, etc).
   * @param itemDueDate The due date of borrowed item.
   */

  public ItemDue (String itemLib, String itemName, String itemType, String itemDueDate) {
    
    this.itemLib = itemLib;
    this.itemName = itemName;
    this.itemType = itemType;
    this.itemDueDate = itemDueDate;
    
  } //end constructor
 
////////////////////////////ACCESSOR/MUTATOR METHODS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\  

  /**
   * Sets the name of an itemDue's Library.
   * 
   * @param itemLib The Name of the Library.
   */
  public void setItemLib(String itemLib) {
    this.itemLib = itemLib;
  }

  /**
   * Returns the name of an itemDue's Library.
   * 
   * @return The Name of the Library.
   */
  public String getItemLib() {
    return this.itemLib;
  }
  
  /**
   * Sets an item's name.
   * 
   * @param itemName The Name of the item.
   */
  public void setItemName(String itemName) {
    this.itemName = itemName;
  }

  /**
   * Returns an item's name.
   * 
   * @return The Name of the item.
   */
  public String getItemName() {
    return this.itemName;
  }

  /**
   * Sets the type of item.
   * 
   * @param itemType The type of item.
   */
  public void setItemType(String itemType) {
    this.itemType = itemType;
  }

  /**
   * Returns the type of item.
   * 
   * @return The type of item.
   */
  public String getItemType() {
    return this.itemType;
  }

  /**
   * Sets the due date for and ItemDue object.
   * 
   * @param itemDueDate The due date for and item.
   */
  public void setItemDueDate(String itemDueDate) {
    this.itemDueDate = itemDueDate;
  }

  /**
   * Returns the due date for and ItemDue object.
   * 
   * @return The due date for and item.
   */
  public String getItemDueDate() {
    return this.itemDueDate;
  }
  
  /**
   * Returns a Comparator object that returns a comparator that allows a collection of
   * ItemDue Objects to be sorted based on Library Location.
   * 
   * @return A comparator that compares ItemDue objects based on Library location
   */
  public static final Comparator<ItemDue> libraryComparator = new Comparator<ItemDue>() {
    public int compare(ItemDue itemDue1, ItemDue itemDue2) {
      return itemDue1.getItemLib().compareTo(itemDue2.getItemLib());
    }
  };
  
  /**
   * Returns a Comparator object that returns a comparator that allows a collection of
   * ItemDue Objects to be sorted based on duedate.
   * 
   * @return A comparator that compares ItemDue objects based on duedate
   */
  public static final Comparator<ItemDue> dueDateComparator = new Comparator<ItemDue>() {
    public int compare(ItemDue itemDue1, ItemDue itemDue2) {
      return itemDue1.getItemDueDate().compareTo(itemDue2.getItemDueDate());
    }
  };
  
  /**
   * Returns a Comparator object that returns a comparator that allows a collection of
   * ItemDue Objects to be sorted based on duedate.
   * 
   * @return A comparator that compares ItemDue objects based on duedate
   */
  public static final Comparator<ItemDue> itemNameComparator = new Comparator<ItemDue>() {
    public int compare(ItemDue itemDue1, ItemDue itemDue2) {
      return itemDue1.getItemName().compareTo(itemDue2.getItemName());
    }
  };
  
  /**
   * Overrides the general hashCode function by returning single value.
   * 
   * @return 0 since hashCode is not used.
   */
  @Override
  public int hashCode() {
    int result = 17;
    result += result * 31 + (this.itemLib == null ? 0 : this.itemLib.hashCode());
    result += result * 31 + (this.itemName == null ? 0 : this.itemName.hashCode());
    result += result * 31 + (this.itemType == null ? 0 : this.itemType.hashCode());
    result += result * 31 + (this.itemDueDate == null ? 0 : this.itemDueDate.hashCode());
    return result;
  }
  
  /**
   * Checks that one ItemDue is equal to another and returns true or false based
   * on this. Overrides the general equals method for Object.
   * 
   * @param o An ItemDue object to compare to. 
   * @return True if the two ItemDue objects are equal.
   */
  @Override
  public boolean equals (Object o) {
    if (!(o instanceof ItemDue)) {
      return false;
    }
    
    ItemDue item = (ItemDue) o;
    return this.itemLib.equals(item.getItemLib()) && this.itemName.equals(item.getItemName()) && 
        this.itemType.equals(item.getItemType()) && this.itemDueDate.equals(item.getItemDueDate());
    
  }
  /**
   * Overrides the toString method to return a formated view of an ItemDue.
   * Contains the library Name, Item Name, Type, and Due Date of Object.
   * 
   * @return A formatted string view of an ItemDue Object.
   */
  @Override
  public String toString() {   
    String format = "|%1$-23s|%2$-50s|%3$-20s|%4$-10s|";
    return String.format(format, this.itemLib, this.itemName.substring(0, 47) + "...", 
        this.itemType, this.itemDueDate);
  }
  
} //end ItemDue class
